import React, { Component } from 'react'
import moment from 'moment'
import { withRouter } from 'react-router-dom'
import XLSX from 'xlsx'
import {
  Card,
  Button, 
  Table, 
  Tag,
  Modal,
  Typography,
  Tooltip,
  message
} from 'antd'
import {
  getArticles,
  deleteArticleById
} from '../../api'

window.moment = moment

const displayTitleMap = {
  id: 'ID',
  title: '标题',
  author: '作者',
  amount: '阅读量',
  createAt: '创建时间'
}

@withRouter

class ArticleList extends Component {
  constructor() {
    super()
    this.state = {
      dataSource: [],
      columns: [],
      total: 0,
      isLoading: false,
      offset: 0,
      limited: 20,
      visible: false,
      deleteArticleContent: '',
      deleteArticleConfirmLoading: false,
      deleteArticleId: null
    }
  }

  // 添加文章
  toAdd = () => {
    this.props.history.push(`/admin/article/add`)
  }

  toEdit = (record) => {
    // this.props.history.push(`/admin/article/edit/${id}`)

    // 隐式传参
    this.props.history.push({
      pathname: `/admin/article/edit/${record.id}`,
      state: {
        title: record.title
      }
    })
  }

  createColumns = (columnKeys) => {
    const columns = columnKeys.map(item => {
      if (item === 'amount') {
        return {
          title: displayTitleMap[item],
          key: item,
          render: (text, record) => {
            const { amount } = record
            // 根据浏览量数字的大小，做一个条件渲染
            // 其他状态字段也可以这样处理。例如：已下单：0，已支付：1，已发货：2，已收货：3，已完成：4
            // const orderStatusMap = {
            //   '0': '已下单',
            //   '1': '已支付',
            //   '2': '已发货',
            //   '3': '已收货',
            //   '4': '已完成'
            // }
            return <Tooltip title="阅读量">
              <Tag color={ amount > 200 ? 'red' : 'green'}>{record.amount}</Tag>
            </Tooltip>
          }
        }
      }

      if (item === 'createAt') {
        return {
          title: displayTitleMap[item],
          key: item,
          render: (text, record) => {
            const { createAt } = record
            return moment(createAt).format('YYYY-MM-DD HH:mm:ss')
          }
        }
      }

      return {
        title: displayTitleMap[item],
        dataIndex: item,
        key: item,
      }
    })

    columns.push({
      title: '操作',
      // dataIndex: 'action',
      key: 'action',
      render: (text, record, index) => {
        // console.log({text, record, index})
        return (
          <Button.Group>
            <Button size="small" type="primary" onClick={this.toEdit.bind(this, record)}>编辑</Button>
            <Button size="small" type="danger" onClick={this.showDeleteArticleModal.bind(this, record)}>删除</Button>
          </Button.Group>
        )
      }
    })

    return columns
  }

  showDeleteArticleModal = (record) => {
    // console.log(record)
    // Modal.confirm({
    //   title: <Typography>是否要删除 <span>{record.title}</span> ?</Typography>,
    //   content: <Typography> <span style={{color: '#f00'}}>{record.title}</span> 删除后将不可恢复</Typography>,
    //   okText: '立马干掉',
    //   cancelText: '继续保留',
    //   onOk() {
    //     deleteArticle(record.id)
    //       .then(res => {
    //         console.log(res)
    //       })
    //   }
    // })
    this.setState({
      visible: true,
      deleteArticleContent: <Typography> <span style={{color: '#f00'}}>{record.title}</span> 删除后将不可恢复</Typography>,
      deleteArticleId: record.id
    })
  }

  deleteArticleCancel = () => {
    this.setState({
      visible: false,
      deleteArticleContent: ''
    })
  }

  deleteArticleOk = () => {
    // console.log('已删除', this.state.deleteArticleId)
    this.setState({
      deleteArticleConfirmLoading: true
    })
    deleteArticleById(this.state.deleteArticleId)
      .then(res => {
        // 删除成功后，给出消息提示
        message.success(res.msg)
        // 重新请求数据
        // this.getData()
        this.setState({
          offset: 0
        }, () => {
          this.getData()
        })
      })
      .catch(err => {

      })
      .finally(() => {
        this.setState({
          deleteArticleConfirmLoading: false,
          visible: false,
          deleteArticleContent: ''
        })
      })
  }

  // setData = (state) => {
  //   // 如果组件未挂载，则不设置状态
  //   if (!this.updater.isMounted(this)) return
  //   this.setState(state)
  // }

  getData = () => {
    this.setState({
      isLoading: true
    })
    getArticles(this.state.offset, this.state.limited)
      .then((res) => {
        // console.log(res)
        const columnKeys = Object.keys(res.list[0])
        const columns = this.createColumns(columnKeys)

        // if (组件还在) {
        //   则setState
        // }
        // console.log(columns)

        console.log(this.updater.isMounted(this))
        // 如果请求完成后，组件已经销毁（如果组件未挂载），则不设置状态
        if (!this.updater.isMounted(this)) return

        this.setState({
          total: res.total,
          columns,
          dataSource: res.list
        })
      })
      .catch((err) => {
        // 处理错误
      })
      .finally(() => {
        if (!this.updater.isMounted(this)) return
        this.setState({
          isLoading: false
        })
      })
  }

  onPageChange = (page, pageSize) => {
    // console.log({page, pageSize})
    this.setState({
      offset: pageSize * (page - 1),
      limited: pageSize
    }, () => {
      // 回调中，根据变更的参数，再次重新请求数据
      this.getData()
    })
  }

  onShowSizeChange = (current, size) => {
    // console.log({current, size})
    // 单页记录变更后，是否跳转到第一页（以下代码是跳转到第一页的代码实现）
    this.setState({
      offset: 0,
      limited: size
    }, () => {
      // 回调中，根据变更的参数，再次重新请求数据
      this.getData()
    })
  }

  // 前端发送ajax请求，后端返回Excel文件的下载地址
  toExcel = () => {
    // console.log('toExcel')
    // 组合数据
    const data = [Object.keys(this.state.dataSource[0])] // [["id","title", "author"]],
    // const dataSource = this.state.dataSource.reduce(result)
    for (let i = 0; i < this.state.dataSource.length; i++) {
      // data.push(Object.values(this.state.dataSource[i]))
      // [[1, 'title1', 'zhangsan']]
      data.push([
        this.state.dataSource[i].id,
        this.state.dataSource[i].title,
        this.state.dataSource[i].author,
        this.state.dataSource[i].amount,
        moment(this.state.dataSource[i].createAt).format('YYYY-MM-DD HH:mm:ss'),
      ])
    }

    /* convert state to workbook */
		const ws = XLSX.utils.aoa_to_sheet(data);
		const wb = XLSX.utils.book_new();
		XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
		/* generate XLSX file and send to client */
		XLSX.writeFile(wb, `articles-${this.state.offset / this.state.limited + 1}-${moment().format('YYYY-MM-DD-HH-mm-ss')}.xlsx`)
  }

  // 组件挂载后
  componentDidMount() {
    console.log(this.updater.isMounted(this))
    this.getData()
  }

  componentWillUnmount() {
    // console.log(this.updater.isMounted(this))
    // 原生方法-取消ajax请求
    // xhr.abort()
    console.log('componentWillUnmount')
  }

  render() {
    return (
      <div>
        <Card 
          title="文章列表" 
          extra={
            <div>
              <Button onClick={this.toAdd}>新建文章</Button>
              <Button onClick={this.toExcel}>导出Excel</Button>
            </div>
          } 
          style={{ width: '100%' }}
        >
          
          <Table
            rowKey={record => record.id} 
            dataSource={this.state.dataSource} 
            columns={this.state.columns} 
            loading={this.state.isLoading}
            pagination={{
              current: this.state.offset / this.state.limited + 1,
              total: this.state.total,
              hideOnSinglePage: true,
              showQuickJumper: true,
              showSizeChanger: true,
              onChange: this.onPageChange,
              onShowSizeChange: this.onShowSizeChange,
              pageSizeOptions: ['10', '20', '30']
            }}
          />

          <Modal
            title="是否确定删除？"
            visible={this.state.visible}
            onOk={this.deleteArticleOk}
            onCancel={this.deleteArticleCancel}
            confirmLoading={this.state.deleteArticleConfirmLoading}
            maskClosable={false}
          >
            <Typography> <span style={{color: '#f00'}}>{this.state.deleteArticleContent}</span> 删除后将不可恢复</Typography>
          </Modal>
        </Card>
      </div>
    )
  }
}

export default ArticleList